﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Diagnostics;
using System.IO;
using System.Xml;
using Lon.IO;

namespace Lon.IO
{
    [XmlRoot("采集机配置")]
    public class SampleDevCfgManager
    {
        [XmlIgnore]
        public  Dictionary<int, SampleDevParam10> devDict = new Dictionary<int, SampleDevParam10>();
        [XmlElement("采集机")]
        public List<SampleDevParam10> Items = new List<SampleDevParam10>();
        private static  SampleDevCfgManager instance = null;
        static String cfgPath;
        
      

        public SampleDevCfgManager()
        { 
        }

        public bool Add(SampleDevParam10 dev)
        {
            if (devDict.ContainsKey(dev.DevNo))
            {
                return false;
            }
            devDict[dev.DevNo] = dev;
            Items.Add(dev);
            return true;
        }

    

        public bool SaveToXml(String path)
        {
            try
            {
                Items.Clear();
                foreach (SampleDevParam10 devParam in devDict.Values)
                {
                    Items.Add(devParam);
                }
                using (StreamWriter sw = new StreamWriter(path, false))
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(SampleDevCfgManager));
                    xmlSerializer.Serialize(sw, this);
                }
            }
            catch (System.Exception ex)
            {
                return false;
            }
            return true;
        }

        public void LoadFormXml(String path)
        {
            SampleDevCfgManager devManager = null;
            using (StreamReader sr = new StreamReader(path))
            {
                try
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(SampleDevCfgManager));
                    devManager = xmlSerializer.Deserialize(sr) as SampleDevCfgManager;
                }
                catch 
                {
                	
                }
              
            }
            for (int i = 0; i < devManager.Items.Count; i++)
            {
                for(int j=0;j<devManager.Items[i].CardItems.Count;j++)
                {
                    List<SampleDevChannelParam10> channels=devManager.Items[i].CardItems[j].ChannelItems;
                  
                }
               
               this.Add(devManager.Items[i]);
            }
        }
    }

    public class SampleDevParam10
    {
        [XmlAttribute("采集机号")]
        public int DevNo;
        [XmlAttribute("预留字节")]
        public int Resvbyte = 0;
        /// <summary>
        /// 区分采集机的类型是为了生成参数时使用不同的生成模板
        /// 1为主要采集开关量
        /// 2为主要采集模拟量
        /// 3为 模拟量加开关量 (道岔电流采集) 为同一配线标准 前三块板预留为开关量位置 
        /// 道岔启动继电器占用一块板 后面两块板用于定位 反位的实际采集 (非强制要求,有利于提高产品的人性化程度)
        /// 4为带智能传感器的采集机
        /// 
        /// 
        /// </summary>
        [XmlAttribute("采集机类型")]
        public int DevType = 1;
        [XmlAttribute("采集机类型描述")]
        public String Desp = "模拟量采集机带道岔电流";
        [XmlElement("采集板")]
        public List<SampleDevCardParam10> CardItems = new List<SampleDevCardParam10>();

        public SampleDevParam10()
        {
        }

        public SampleDevParam10(int devNo, int devType)
        {
            this.DevNo = devNo;
            this.DevType = devType;
            SampleDevCardParam10 card;
            switch (DevType)
            {
                case 0:
                    card = new SampleDevCardParam10((int)CardTypeEnum.DigitControlBoard);
                    this.AddCard(card);
                    break;
                case 1:
                    card = new SampleDevCardParam10((int)CardTypeEnum.AnalogSampleBoard);
                    this.AddCard(card);
                    break;
                case 2:
                    for (int i = 0; i < 3; i++)
                    {
                        card = new SampleDevCardParam10((int)CardTypeEnum.DigitControlBoard);
                        this.AddCard(card);
                    }
                    card = new SampleDevCardParam10((int)CardTypeEnum.AnalogSampleBoard);
                    this.AddCard(card);
                    break;
                case 3:
                    card = new SampleDevCardParam10((int)CardTypeEnum.FSKSampleBoard);
                    this.AddCard(card);
                    break;
                default:
                    //DoNothing
                    break;


            }

        }

        public bool AddCard(SampleDevCardParam10 card)
        {
            if (ContainsCard(card)) return false;
            
            CardItems.Add(card);
            return true;
        }

        public bool ContainsCard(int cardNo)
        {
            foreach (SampleDevCardParam10 card in CardItems)
            {
                if (cardNo == card.CardNo)
                {
                    return true;
                }
            }
            return false;
        }

        public bool ContainsCard(SampleDevCardParam10 card)
        {
            return ContainsCard(card.CardNo);
        }

        public byte[] ToSetByteArray()
        {
            List<byte> list = new List<byte>(2000);
            list.Add((byte)this.CardItems.Count);
            list.Add((byte)this.Resvbyte);
            for (int i = 0; i < CardItems.Count; i++)
            {
                list.AddRange(CardItems[i].ToSetByteArray());
            }
            return list.ToArray();
        }
    
          

    }

    /// <summary>
    /// ToDo:暂时未做对通道类型的防护处理
    /// </summary>
    public class SampleDevCardParam10
    {
        [XmlAttribute]
        public int CardNo;
        [XmlAttribute("板类型")]
        public int CardType = 3;
        [XmlAttribute("预留参数")]
        public int ResvParam = 0;
        [XmlElement("通道")]
        public List<SampleDevChannelParam10> ChannelItems = new List<SampleDevChannelParam10>();
        [XmlIgnore]
        private int track25HzRef = 47;
        [XmlIgnore]
        private bool HavePhase3Current;
        [XmlIgnore]
        private static readonly int[] maxChannelsAboutTable
            = new int[]{48, 1,95,48,0,
                        0, 0, 0, 0,18,
                        8, 8, 8, 8,8
                       };
        #region
        public SampleDevCardParam10()
        {
        }
        public SampleDevCardParam10(int cardType)
        {
            if (CardType == (int)CardTypeEnum.DigitSampleBoard)
            {
                for (int i = 0; i < 48; i++)
                {
                    SampleDevChannelParam10 channel = new SampleDevChannelParam10(2);
                    ChannelItems.Add(channel);
                }
            }
        }
        public SampleDevCardParam10(SampleDevCardParam10 card)
        {
            this.CardNo = card.CardNo;
            this.CardType = card.CardType;
            this.HavePhase3Current = card.HavePhase3Current;
            for (int i = 0; i < card.ChannelItems.Count; i++)
            {
                ChannelItems.Add(new SampleDevChannelParam10(card.ChannelItems[i]));

            }
        }
        public bool AddChannel(SampleDevChannelParam10 param)
        {
           if (param.ChannelNo < 0)
            {
                param.ChannelNo = ChannelItems.Count;
            }
            ChannelItems.Add(param);
            return true;
        }
      
        /// <summary>
        /// 添加一个25Hz轨道电路
        /// </summary>
        /// <param name="force">如果参考通道已被占用是否强制替换</param>
        /// <returns></returns>
        //public bool AddTrack25Hz(int channelNo, bool force)
        //{
        //    if (ChannelItems.Count > track25HzRef)
        //    {
        //        if (ChannelItems[track25HzRef].ChannelType != 0x33 && force == false) return false;

        //    }
        //    else
        //    {
        //        this.AddChannel(track25HzRef, new SampleDevChannelParam10());

        //    }

        //    ChannelItems[track25HzRef].ChannelType = 0x33;
        //    ChannelItems[track25HzRef].BytesCount = 6;

        //    this.AddChannel(channelNo, new SampleDevChannelParam10());
        //    ChannelItems[track25HzRef].ChannelType = 0x33;
        //    ChannelItems[track25HzRef].RelatedCard1 = this.CardNo;
        //    ChannelItems[track25HzRef].RelatedChannel1 = this.track25HzRef;
        //    return true;
        //}
        /// <summary>
        /// 从后向前查找一个空通道如无空通道返回 -1
        /// </summary>
        /// <returns></returns>
        public int FindUnusedChannel()
        {
            int i = 44;
            if (ChannelItems[i].ChannelType != 0xff) return -1;
            for (i = ChannelItems.Count - 4; i > 0; i--)
            {
                if (ChannelItems[i - 1].ChannelType != 0xf0) break;

            }
            return i;
        }

     
        #endregion

        public byte[] ToSetByteArray()
        {
            List<byte> list = new List<byte>(500);
            list.Add((byte)this.CardNo);
            list.Add((byte)this.CardType);
            list.Add((byte)this.ChannelItems.Count);
            list.Add((byte)this.ResvParam);
            //II型传感器需要通道参数
            if (this.CardType >= 16) return list.ToArray();
            for (int i = 0; i < ChannelItems.Count; i++)
            {
                list.AddRange(ChannelItems[i].ToSetByteArray());
            }
            return list.ToArray();
        }
      
  
    }

    public class SampleDevChannelParam10
    {
        [XmlAttribute("通道号")]
        public int ChannelNo;
        [XmlAttribute("通道类型")]
        public int ChannelType=0xf0;
        [XmlAttribute("字节数")]
        public int BytesCount=2;
        [XmlAttribute("关联板号1")]
        public int RelatedCard1=0xff;
        [XmlAttribute("关联通道号1")]
        public int RelatedChannel1;
        [XmlAttribute("关联板号2")]
        public int RelatedCard2=0xff;
        [XmlAttribute("关联通道号2")]
        public int RelatedChannel2=0xff;
        [XmlAttribute("附加参数")]
        public int OtherParam;

        public SampleDevChannelParam10()
        {

        }
        public SampleDevChannelParam10(int type)
        {
            this.ChannelType = type;
         
        }

        public SampleDevChannelParam10(SampleDevChannelParam10 channel)
        {
            ChannelNo = channel.ChannelNo;
            ChannelType = channel.ChannelType;
            BytesCount = channel.ChannelNo;
            RelatedCard1 = channel.RelatedCard1;
            RelatedCard2 = channel.RelatedCard2;
            RelatedChannel1 = channel.RelatedChannel1;
            RelatedChannel2 = channel.RelatedChannel2;
            OtherParam = channel.OtherParam;

        }

  
        public byte[] ToSetByteArray()
        {
            List<byte> list = new List<byte>();      
            list.Add((byte)this.ChannelType);
            list.Add((byte)this.BytesCount);
            list.Add((byte)this.RelatedCard1);
            list.Add((byte)this.RelatedChannel1);
            list.Add((byte)this.RelatedCard2);
            list.Add((byte)this.RelatedChannel2);
            list.Add((byte)(this.OtherParam&0xff));
            list.Add((byte)(this.OtherParam >> 8));     
            return list.ToArray();
        }
    }

  
}
